package com.focus.pay.ali.action.notice;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.focus.pay.ali.config.AliPayConfig;
import com.focus.pay.ali.constant.AliMethod;
import com.focus.pay.ali.model.notice.AliPayModelOrder;
import com.focus.pay.core.annation.PayNoticeHandler;
import com.focus.pay.core.enums.Channel;
import com.focus.pay.core.exception.ExceptionEnum;
import com.focus.pay.core.exception.PayException;
import com.focus.pay.core.pay.PayNoticeInterface;
import com.focus.pay.core.utils.AssertUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author 赵参谋
 * @version $
 * =========================================================================
 * 变更履历：
 * -------------------------------------------------------------------------
 * 变更编号     变更时间    变更人   变更原因    变更内容
 * -------------------------------------------------------------------------
 * <p>
 * @description：支付宝订单回调
 * @date 2022/1/12 13:57
 **/
@PayNoticeHandler(channel = Channel.AliPay,method = AliMethod.Order)
public class AliPayOrderNotice implements PayNoticeInterface<AliPayModelOrder, HttpServletRequest, AliPayConfig> {

    private static final Log log = LogFactory.get();

    /**
     * 支付回调
     * @param httpServletRequest http请求
     * @param aliPayConfig 支付宝配置
     * @return AliPayCallback 支付回调参数
     * @throws PayException 支付异常
     */
    @Override
    public AliPayModelOrder payCallback(HttpServletRequest httpServletRequest, AliPayConfig aliPayConfig) throws PayException {
        Map<String, String> callbackParams = httpServletRequest.getParameterMap().entrySet().stream()
                .filter(item -> item.getValue().length>0)
                .collect(Collectors.toMap(
                        item -> item.getKey(),
                        item -> Stream.of(item.getValue()).collect(Collectors.joining(","))
                ));
        return process(aliPayConfig, callbackParams);
    }

    /**
     * 支付回调
     * @param jsonContent 字符串请求
     * @param aliPayConfig 支付宝配置
     * @return AliPayCallback 支付回调参数
     * @throws PayException 支付异常
     */
    public AliPayModelOrder payCallback(String jsonContent, AliPayConfig aliPayConfig) throws PayException {
        JSONObject jsonObject = JSONUtil.parseObj(jsonContent);
        return process(aliPayConfig, jsonObject.toBean(Map.class));
    }

    /**
     * 支付回调
     * @param map map请求
     * @param aliPayConfig 支付宝配置
     * @return AliPayCallback 支付回调参数
     * @throws PayException 支付异常
     */
    public AliPayModelOrder payCallback(Map map, AliPayConfig aliPayConfig) throws PayException {
        return process(aliPayConfig, map);
    }


    private AliPayModelOrder process(AliPayConfig aliPayConfig, Map<String, String> callbackParams) {
        try{
            //验签
            Boolean verify = AlipaySignature.verifyV1(callbackParams, aliPayConfig.getPublicKey(), aliPayConfig.getCharset(), aliPayConfig.getSignType());

            AssertUtils.isTrue(verify,() -> new PayException(ExceptionEnum.VERIFY_ERROR));

            return BeanUtil.toBean(callbackParams, AliPayModelOrder.class);

        }catch (PayException payException){
            log.error(payException.getExceptionMsg(),payException);
            return null;
        }catch (AlipayApiException ex){
            log.error(ex.getErrMsg(),ex);
            return null;
        }
    }


}
